package com.wang.wangrpc.server.tcp;

import cn.hutool.core.util.IdUtil;
import com.wang.wangrpc.RpcApplication;
import com.wang.wangrpc.model.RpcRequest;
import com.wang.wangrpc.model.RpcResponse;
import com.wang.wangrpc.model.ServiceMetaInfo;
import com.wang.wangrpc.protocol.*;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @Author 王子旭
 * @Date 2025/04/05 17:05
 * @Version 1.0
 */
@Slf4j
public class VertxTcpClient {
   public static RpcResponse doRequest(RpcRequest rpcRequest, ServiceMetaInfo serviceMetaInfo) throws ExecutionException, InterruptedException {
       // 发送 TCP 请求
       Vertx vertx = Vertx.vertx();
       NetClient netClient = vertx.createNetClient();
       CompletableFuture<RpcResponse> responseFuture = new CompletableFuture<>();
       netClient.connect(serviceMetaInfo.getServicePort(),serviceMetaInfo.getServiceHost(),
               result->{
                   if (result.failed()) {
                       log.error("Failed to connect to TCP server");
                       responseFuture.completeExceptionally(new RuntimeException("Failed to connect to TCP server"));
                       return;
                   }
                   log.info("Connected to TCP server");
                   NetSocket socket = result.result();
                   // 发送数据
                   // 构造消息
                   ProtocolMessage<Object> protocolMessage = new ProtocolMessage<>();
                   ProtocolMessage.Header header = new ProtocolMessage.Header();
                   header.setMagic(ProtocolConstant.PROTOCOL_MAGIC);
                   header.setVersion(ProtocolConstant.PROTOCOL_VERSION);
                   header.setSerializer((byte) ProtocolMessageSerializerEnum.getEnumByValue(RpcApplication.getRpcConfig().getSerializer()).getKey());
                   header.setType((byte) ProtocolMessageTypeEnum.REQUEST.getKey());
                   header.setRequestId(IdUtil.getSnowflakeNextId());
                   protocolMessage.setHeader(header);
                   protocolMessage.setBody(rpcRequest);
                   // 编码请求
                   try {
                       Buffer encodeBuffer = ProtocolMessageEncoder.encode(protocolMessage);
                       socket.write(encodeBuffer);
                   } catch (IOException e) {
                       throw new RuntimeException("协议消息编码错误");
                   }
                   // 接受响应
                   socket.handler(buffer->{
                       try {
                           ProtocolMessage<RpcResponse> rpcResponseProtocolMessage = (ProtocolMessage<RpcResponse>) ProtocolMessageDecoder.decode(buffer);
                           responseFuture.complete(rpcResponseProtocolMessage.getBody());
                       } catch (IOException e) {
                           throw new RuntimeException("协议消息编码错误");
                       }
                   });
               });
       RpcResponse rpcResponse = responseFuture.get();
       // 关闭连接
       netClient.close();
       return rpcResponse;
   }

}
